package cn.ilikes.tools.hbase.jpa.schemas.processors;

import java.util.ArrayList;
import java.util.Map.Entry;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.FetchType;

import org.slf4j.Logger;

import cn.ilikes.tools.hbase.jpa.JPAHbasePersistenUnitEnv;
import cn.ilikes.tools.hbase.jpa.metadatas.IEntityMetaData;
import cn.ilikes.tools.hbase.jpa.metadatas.IEntityMetaDataFactory;
import cn.ilikes.tools.hbase.jpa.metadatas.elements.EntityFields;
import cn.ilikes.tools.hbase.jpa.metadatas.elements.EntityFieldsImpl;
import cn.ilikes.tools.hbase.jpa.metadatas.elements.IndexField;
import cn.ilikes.tools.hbase.jpa.metadatas.elements.JPAFieldImpl;
import cn.ilikes.tools.hbase.jpa.metadatas.elements.Relation;
import cn.ilikes.tools.hbase.jpa.metadatas.elements.Relation.ForeignKey;
import cn.ilikes.tools.logs.Loggerfactory;
import cn.ilikes.tools.untils.ObjectUtils;

public class TableFieldSchemasProcessor implements ISchemasProcessor {

	private Logger logger = Loggerfactory.instance(TableFieldSchemasProcessor.class);

	@Override
	public void processorTableSchemas(JPAHbasePersistenUnitEnv hbasePersistenUnitEnv) {
		IEntityMetaDataFactory entityMetaDataFactory = hbasePersistenUnitEnv.getEntityMetaDataFactory();
		Set<IEntityMetaData> entityMetaDatas = entityMetaDataFactory.listAllIEntityMetaData();
		for (IEntityMetaData entityMetaData : entityMetaDatas) {
			for (Entry<String, EntityFields> entityField : entityMetaData.getEntityFields().entrySet()) {
				EntityFields entityFields = entityField.getValue();
				if (!ObjectUtils.isRelation(entityFields))
					continue;
				Relation relation = entityFields.getjPAField().getRelation();
				String joinColumnName = relation.getJoinColumnName();

				if (joinColumnName != null && !joinColumnName.isEmpty()) {
					if (relation.getType().equals(ForeignKey.ONE_TO_MANY)) {
						Class targetEntityClass = relation.getTargetEntity();
						IEntityMetaData targetEntityMetaData = entityMetaDataFactory.selectIEntityMetaData(targetEntityClass);
						EntityFields entityFields_ = targetEntityMetaData.findEntityFieldsByJPAColumn(joinColumnName);

						//@ONE_TO_MANY have not mappdby
						//@JoinColumnName

						// new  create foreignKey  entityfields
						if (entityFields_ == null) {
							//throw new JPAHBaseSchemaRuntimeException(" s : " + entityMetaData.getEntityName() + " JoinColumnName " + JoinColumnName
							//+ " not  in " + targetEntityClass.getSimpleName());
							//
							EntityFieldsImpl newEntityFields = new EntityFieldsImpl(EntityFields.EntityFieldsType.RoreignKey);
							targetEntityMetaData.getEntityFields().put(targetEntityClass.getSimpleName(), newEntityFields);
							newEntityFields.setFieldName(targetEntityClass.getSimpleName());
							//IndexField
							IndexField indexField = entityFields.getIndexField();
							newEntityFields.setIndexField(indexField);
							//JPAField
							JPAFieldImpl jpaField = new JPAFieldImpl();

							//Field property, Class<?> targetEntity, Class<?> propertyType, FetchType fetchType,
							//List<CascadeType> cascades, boolean optional, String mappedBy, Relation.ForeignKey type
							Relation newRelation = new Relation(null, targetEntityClass, null, FetchType.LAZY, new ArrayList<CascadeType>(), false, null,
									ForeignKey.MANY_TO_ONE);
							newRelation.setJoinColumnName(joinColumnName);
							newRelation.setColumnName(joinColumnName);
							jpaField.setRelation(newRelation);
							newEntityFields.setjPAField(jpaField);

						}

						//

					} else {
						if (Loggerfactory.isdebug(logger))
							Loggerfactory.debug(logger, " s  :   " + entityMetaData.getEntityClazz().getSimpleName() + "  add  relation column :   "
									+ joinColumnName);
						//						System.out.println("--------------  > "+ " s  :   " + entityMetaData.getEntityClazz().getSimpleName() + "  add  relation column :   "+ joinColumnName);
						relation.setColumnName(joinColumnName);
					}

				}

			}
		}
	}
}
